/***************************************************************************
 *   Copyright (C) 2008 by Rysiek Krol,,,   *
 *   rysiek@Babylon2   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "utils.h"

#include "rexifdata.h"
#include "picturelistwidgetitem.h"

#include <QImage>
#include <QFileInfo>
#include <QDomDocument>
#include <QListWidgetItem>

#include <zlib.h>

Utils::Utils()
{
}


Utils::~Utils()
{
}

/**
* Generates Icon
*/
QImage Utils::generateIcon(const QFileInfo & filePatch)
{

    QImage result;
    if (filePatch.exists())
    {
        if ( filePatch.isFile() )
        {
            RExifData *exifData = new RExifData(filePatch.absoluteFilePath().toUtf8().data());
            if (exifData->isExif())
            {
                result = exifData->getThumbnail();
            }
            if (result.isNull())
            {

                if (result.load( filePatch.absoluteFilePath() ))
                    result = result.scaled ( QSize ( 150,150 ),Qt::KeepAspectRatio );
            }
            delete exifData;
        }
    }
    return result;

}


/**
* Rozpakowuje plik
* @param QFileInfo - Plik do rozpakowania
* @param QString - Wskaznik do QStringa do ktorego chemy rozpakowac plik
*/
int Utils::unGzip(QFileInfo * fileInfo, QString * dest)
{
    char buf[1024];
    gzFile pliczek;
    int res = 0;
    const char *fileName;
    QByteArray array = fileInfo->filePath().toLocal8Bit();
    fileName = array.data();
    pliczek = gzopen ( fileName, "rb" );
    res = gzread ( pliczek, buf, 1024 );
    gzclose(pliczek);
    *dest = buf;
    *dest = Utils::textConverter(*dest);
    return res;
}

/**
* Sorts Widget List
*/
void Utils::sortItems(QList< QFileInfo > * lista, int beg, int end,  Property::SortMethod sortMethod)
{

    if ( beg<end )
    {
        int m=beg;
        for ( int i=beg+1;i<=end;i++ )
        {
            if ( compareItems(lista->at ( i ), lista->at ( beg ), sortMethod) ) lista->swap ( ++m,i );
        }
        lista->swap ( beg,m );
        sortItems ( lista,beg,m-1, sortMethod );
        sortItems ( lista,m+1,end, sortMethod );
    }

}

/**
* Returns true, if items should be swaped by sort algorytm
*/
bool Utils::compareItems(QFileInfo firstFile, QFileInfo secondFile,  Property::SortMethod sortMethod)
{
    switch (sortMethod)
    {
    case Property::ByCommentDate:
    {
        PictureListWidgetItem * firstItem = new PictureListWidgetItem(firstFile);
        PictureListWidgetItem * secondItem = new PictureListWidgetItem(secondFile);
        if ( (firstItem->isDate() && secondItem->isDate()) && ( firstItem->getDateTime() <secondItem->getDateTime() ) )
        {
            delete firstItem;
            delete secondItem;
            return true;
        }
        break;
    }
    case Property::ByFileName:
        if ( firstFile.fileName() < secondFile.fileName() ) return true;
        break;
    }
    return false;
}


/**
* Zakodowywuje polskie znaczki (bez tej funkcji gThumb nie potrafi odczytac komentarza z Polskimi znakami)
* @param string - string do zdekodowania
* @return QString - zdekodowany QString
*/
QString Utils::encodeCharacters(QString string)
{

string.replace("ą","&#x105;"); //a
string.replace("Ą","&#x104;"); //A
string.replace("ę","&#x119;"); //e
string.replace("Ę","&#x118;"); //E
string.replace("ć","&#x107;"); //c
string.replace("Ć","&#x106;"); //C
string.replace("ó","&#xF3;"); //o
string.replace("Ó","&#xD3;"); //O
string.replace("ł","&#x142;"); //l
string.replace("Ł","&#x141;"); //L
string.replace("ń","&#x144;"); //n
string.replace("Ń","&#x143;"); //N
string.replace("ż","&#x17C;"); //z
string.replace("Ż","&#x17B;"); //Z
string.replace("ź","&#x17A;"); //x
string.replace("Ź","&#x179;"); //X

    return string;
}

/**
* Konwetruje QString zapewniajac poprawne wyswietlanie polskich znakÃÂ³w
*/
QString Utils::textConverter(QString string)
{

string.replace("&#x105;","ą"); //a
string.replace("&#x104;","Ą"); //A
string.replace("&#x119;","ę"); //e
string.replace("&#x118;","Ę"); //E
string.replace("&#x107;","ć"); //c
string.replace("&#x106;","Ć"); //C
string.replace("&#xF3;","ó"); //o
string.replace("&#xD3;","Ó"); //O
string.replace("&#x142;","ł"); //l
string.replace("&#x141;","Ł"); //L
string.replace("&#x144;","ń"); //n
string.replace("&#x143;","Ń"); //N
string.replace("&#x17C;","ż"); //z
string.replace("&#x17B;","Ż"); //Z
string.replace("&#x17A;","ź"); //x
string.replace("&#x179;","Ź"); //X

        return string;

}

/**
* archiwizuje i zapisuje do pliku komentarz
* @Param commentString - komentarz
* @param itemIndex - numer indexu pliku w thia->selectedList
*/
void Utils::writeComment(QString commentString, int itemIndex, QList<QListWidgetItem*> selectedList)
{
    QFileInfo fileInfo = ((PictureListWidgetItem*)selectedList.at(itemIndex))->getFile();
    QDir dir = fileInfo.dir();
    if (!dir.exists(".comments")) dir.mkdir(".comments");
    dir.cd(".comments");
    //setting comment directory windows attribute to hidden
#ifdef WINDOWS
    LPCTSTR winFileName = (LPCTSTR) dir.absolutePath().toStdString ().c_str()
                          SetFileAttributes( winFileName ,FILE_ATTRIBUTE_HIDDEN);
    delete winFileName;
#endif
    QString fileName = fileInfo.fileName();
    fileName = fileName + ".xml";
    fileName = dir.filePath(fileName);
    char buf[commentString.size()];
    QByteArray array = commentString.toLocal8Bit();
    char* buffer = array.data();
    for (unsigned int i=(unsigned int)0; i < (unsigned int)commentString.size();i++)
    {
        buf[i] = *buffer++;
    }
    gzFile pliczek;
    const char *filePath;
    array = fileName.toLocal8Bit();
    filePath = array.data();
    pliczek = gzopen ( filePath, "wb" );
    gzwrite(pliczek, buf, sizeof(buf));
    gzclose(pliczek);

}


/**
* Builds new comment XML document. In Future there have to be XML classes
*/
QDomDocument Utils::buildNewComment()
{
    QDomDocument doc("");

    /*   QDomElement root = doc.createElement("Comment");
       root.setAttribute("format", "2.0");
       doc.appendChild(root);

       QDomElement element = doc.createElement("Note");
       root.appendChild(element);
       element = doc.createElement("Place");
       root.appendChild(element);
       element = doc.createElement("Time");
       root.appendChild(element);
       element = doc.createElement("Keywords");
       root.appendChild(element);
    QDomText
    */
    QString docString = "<?xml version=\"1.0\"?>\n<Comment format=\"2.0\"><Place></Place><Time></Time><Note/><Keywords></Keywords></Comment>";
    doc.setContent(docString);
    return doc;

}


